package com.nulldev.util.graphics.legacy;

import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.Toolkit;

import javax.swing.JPanel;

import com.nulldev.util.concurrency.threadIt.v4.emapi.ExecutorManager;

public abstract class LegacySmoothCanvas extends JPanel implements LegacyPaintCallback {
	private static final long serialVersionUID = 9110371053108269074L;
	public volatile long FRAME_RATE = (1000L / 144L);
	public volatile boolean vSync = true;
	public volatile boolean aa = false;
	private volatile LegacyPaintMethod method = LegacyPaintMethod.DEFAULT;

	private volatile boolean stop = false;

	public LegacySmoothCanvas() {
		super();
		setOpaque(true);
		setDoubleBuffered(true);
		setIgnoreRepaint(false);
		ExecutorManager.get().queueTask(new Runnable() {

			@Override
			public void run() {
				while (true) {
					if (LegacySmoothCanvas.this.stop) {
						break;
					}
					try {
						if (getBackground() == LegacyColorUtil.TRANSPARENT) {
							setBackground(LegacyColorUtil.TRANSPARENT);
						}

						if (method == LegacyPaintMethod.DEFAULT) {
							paint(getGraphics());
						} else if (method == LegacyPaintMethod.PAINT_IMM) {
							paintImmediately(getBounds());
						} else if (method == LegacyPaintMethod.REPAINT) {
							repaint();
						} else if (method == LegacyPaintMethod.REPAINT_DELAYED) {
							repaint(FRAME_RATE * 1000);
						}
						if (vSync) {
							Toolkit.getDefaultToolkit().sync();
						}
						if (FRAME_RATE > 0) {
							try {
								Thread.sleep(FRAME_RATE);
							} catch (Exception e) {
							}
						}
					} catch (Exception e) {
					}
				}
			}
		});
	}

	@Override
	public void paintComponent(final Graphics g) {
		super.paintComponent(g);
		if (this.aa) {
			((Graphics2D) g).setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
		}
		ExecutorManager.get().submit(() -> {
			this.drawCanvas((Graphics2D) g);
			return null;
		}).waitTillCompletion();
	}

	public boolean isVSyncEnabled() {
		return this.vSync;
	}

	public boolean isAAEnabled() {
		return this.aa;
	}

	public void setAAEnabled(final boolean state) {
		this.aa = state;
	}

	public void setVSyncEnabled(final boolean state) {
		this.vSync = state;
	}

	public void setFPS(final long FPS) {
		if (FPS > 0L) {
			this.FRAME_RATE = (1000L / (FPS + 6));
		} else {
			this.FRAME_RATE = 0;
		}
	}

	public void usePaintMethod(final LegacyPaintMethod method) {
		this.method = method;
	}

	@SuppressWarnings("unused")
	private volatile Color cb = Color.WHITE;

	@Override
	public void setBackground(final Color color) {
		super.setBackground(color);
		this.cb = color;
	}

	public void dispose() {
		this.stop = true;
	}

	public boolean isGLDrawing() {
		return false;
	}

	public String getRendererString() {
		return "Swing (Java)";
	}
}
